<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<!-- 
	Copyright (C) 2007, 2008, 2009, 2010, 2011. PARP Research Group.
	<http://perception.inf.um.es>
	University of Murcia, Spain.

	This file is part of the QVision library.

	QVision is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, version 3 of the License.

	QVision is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with QVision. If not, see <http://www.gnu.org/licenses/>.
-->

<html><head><meta http-equiv="content-Type" content="text/html;charset=UTF-8">
<title>QVision: Qt&#39;s Image, Video and Computer Vision Library</title>
<meta name="title" content="QVision" />
<meta name="dc.title" content="QVision" />
<meta name="url" content="http://perception.inf.um.es/QVision" />
<meta name="author" content="PARP Research Group - http://perception.inf.um.es" />
<meta name="revisit-after" content="30 DAYS"/>
<meta name="robots" content="index,follow"/>
<meta name="classification" content="*">
<meta name="rating" content="Safe For Kids">
<meta name="distribution" content="GLOBAL"/>
<meta name="description" content="Qt's Image, Video and Computer Vision Library"/>
<meta name="page-topic" content="Computer Vision research and prototype programming"/>
<meta name="geo.country" content="ES" />

<!--
Keywords:
By license:		open source, gnu, lgpl, gpl, free
By theme:		computer vision, image processing, robotics, programming, source, development
By usage:		library, toolkit, framework, prototype, application
By programming specs:	object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping
Interoperability with:	Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack
Functionallity:		image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface
Main data-types:	matrix, vector, tensor, quaternion, image, polyline
Video sources:		webcam, camera, stream
Devices:		embedded, desktop computer, laptop, mini-laptop
Authors:		PARP research group. University of Murcia, Spain.
-->

<meta name="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="title" content="QVision"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="tabs.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="favicon.ico" />
</head><body>

<table width="100%"><tr>
	<td><a href="http://perception.inf.um.es/"><img src="parp.png" border="0" /> <big>PARP Research Group</big></a></td>
	<td align="right"><a href="http://www.um.es/"><big>Universidad de Murcia</big> <img src="um.png" border="0" /></a></td>
</tr></table>

<hr /><br />

<table width="95%" align="center"><tr><td>

<!-- Generated by Doxygen 1.6.3 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
          <form id="FSearchBox" action="search.php" method="get">
            <img id="MSearchSelect" src="search/search.png" alt=""/>
            <input type="text" id="MSearchField" name="query" value="Search" size="20" accesskey="S" 
                   onfocus="searchBox.OnSearchFieldFocus(true)" 
                   onblur="searchBox.OnSearchFieldFocus(false)"/>
          </form>
        </div>
      </li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>File&nbsp;Members</span></a></li>
    </ul>
  </div>
<h1>examples/completeExample/completeExample.cpp</h1><a href="completeExample_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> *      Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012. PARP Research Group.</span>
<a name="l00003"></a>00003 <span class="comment"> *      &lt;http://perception.inf.um.es&gt;</span>
<a name="l00004"></a>00004 <span class="comment"> *      University of Murcia, Spain.</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> *      This file is part of the QVision library.</span>
<a name="l00007"></a>00007 <span class="comment"> *</span>
<a name="l00008"></a>00008 <span class="comment"> *      QVision is free software: you can redistribute it and/or modify</span>
<a name="l00009"></a>00009 <span class="comment"> *      it under the terms of the GNU Lesser General Public License as</span>
<a name="l00010"></a>00010 <span class="comment"> *      published by the Free Software Foundation, version 3 of the License.</span>
<a name="l00011"></a>00011 <span class="comment"> *</span>
<a name="l00012"></a>00012 <span class="comment"> *      QVision is distributed in the hope that it will be useful,</span>
<a name="l00013"></a>00013 <span class="comment"> *      but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00014"></a>00014 <span class="comment"> *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<a name="l00015"></a>00015 <span class="comment"> *      GNU Lesser General Public License for more details.</span>
<a name="l00016"></a>00016 <span class="comment"> *</span>
<a name="l00017"></a>00017 <span class="comment"> *      You should have received a copy of the GNU Lesser General Public</span>
<a name="l00018"></a>00018 <span class="comment"> *      License along with QVision. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<a name="l00019"></a>00019 <span class="comment"> */</span>
<a name="l00020"></a>00020 
<a name="l00035"></a>00035 <span class="preprocessor">#ifndef DOXYGEN_IGNORE_THIS // Do not generate any doxygen documentation from here on.</span>
<a name="l00036"></a>00036 <span class="preprocessor"></span>
<a name="l00037"></a>00037 <span class="comment">/************************************** INCLUDE SECTION **************************************/</span>
<a name="l00038"></a>00038 
<a name="l00039"></a>00039 <span class="comment">// Main QVApplication class (always needed):</span>
<a name="l00040"></a>00040 <span class="preprocessor">#include &lt;QVApplication&gt;</span>
<a name="l00041"></a>00041 
<a name="l00042"></a>00042 <span class="comment">// Video source reader block (virtually always needed):</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include &lt;QVVideoReaderBlock&gt;</span>
<a name="l00044"></a>00044 
<a name="l00045"></a>00045 <span class="comment">// Main GUI, image  and function plot windows:</span>
<a name="l00046"></a>00046 <span class="preprocessor">#include &lt;QVDefaultGUI&gt;</span>
<a name="l00047"></a>00047 <span class="preprocessor">#include &lt;QVImageCanvas&gt;</span>
<a name="l00048"></a>00048 <span class="preprocessor">#include &lt;QVFunctionPlot&gt;</span>
<a name="l00049"></a>00049 
<a name="l00050"></a>00050 <span class="comment">// Image processing and matrix functionality:</span>
<a name="l00051"></a>00051 <span class="preprocessor">#include &lt;qvipp.h&gt;</span>
<a name="l00052"></a>00052 <span class="preprocessor">#include &lt;qvip.h&gt;</span>
<a name="l00053"></a>00053 <span class="preprocessor">#include &lt;qvmatrixalgebra.h&gt;</span>
<a name="l00054"></a>00054 
<a name="l00055"></a>00055 <span class="comment">/************************************** CUSTOMIZED WINDOWS SECTION **************************************/</span>
<a name="l00056"></a>00056 
<a name="l00057"></a>00057 <span class="comment">// First, you need to declare new types that are going to be used as properties:</span>
<a name="l00058"></a>00058 <span class="keyword">typedef</span> QMap&lt;sFloat,QPointF&gt; TMapFloatPoints;
<a name="l00059"></a>00059 Q_DECLARE_METATYPE(TMapFloatPoints);
<a name="l00060"></a>00060 <span class="keyword">typedef</span> QList&lt;QLineF&gt; TListLines;
<a name="l00061"></a>00061 Q_DECLARE_METATYPE(TListLines);
<a name="l00062"></a>00062 
<a name="l00063"></a>00063 <span class="comment">// Two new customized QVImageCanvas subclasses: one to draw float corner response image, with corresponding maximum</span>
<a name="l00064"></a>00064 <span class="comment">// response points, and another to draw Canny image, with regression lines in selected squares:</span>
<a name="l00065"></a>00065 <span class="keyword">class </span>ResponseImageCanvas : <span class="keyword">public</span> <a class="code" href="classQVImageCanvas.html" title="Display widget for QVImage objects and other data types.">QVImageCanvas</a> {
<a name="l00066"></a>00066     <span class="keyword">public</span>:
<a name="l00067"></a>00067         ResponseImageCanvas(QString name) : <a class="code" href="classQVImageCanvas.html" title="Display widget for QVImage objects and other data types.">QVImageCanvas</a>(name) {
<a name="l00068"></a>00068             <span class="comment">// Add extra properties to draw in canvas:</span>
<a name="l00069"></a>00069             addProperty&lt;QMap&lt;sFloat,QPointF&gt; &gt;(<span class="stringliteral">&quot;Max points&quot;</span>, inputFlag);
<a name="l00070"></a>00070         } ;
<a name="l00071"></a>00071         <span class="keywordtype">void</span> <a class="code" href="classQVImageCanvas.html#a0040df759739f50e9235547f1055844a" title="Display user defined data types method.">custom_viewer</a>() {
<a name="l00072"></a>00072             <span class="comment">// Read properties to draw in canvas:</span>
<a name="l00073"></a>00073             QMap&lt;sFloat,QPointF&gt; maxPoints = getPropertyValue&lt; QMap&lt;sFloat,QPointF&gt; &gt;(<span class="stringliteral">&quot;Max points&quot;</span>);
<a name="l00074"></a>00074 
<a name="l00075"></a>00075             <span class="comment">// Use getQVPainter() and standard QT QPainter class methods to draw in canvas:</span>
<a name="l00076"></a>00076             <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;setPen(Qt::yellow);
<a name="l00077"></a>00077             QMap&lt;sFloat, QPointF&gt;::iterator i = maxPoints.begin();
<a name="l00078"></a>00078             <span class="keywordtype">int</span> order = 1;
<a name="l00079"></a>00079             <span class="keywordflow">while</span> (i != maxPoints.end()) {
<a name="l00080"></a>00080                 QPointF point = i.value() + QPointF(0.5,0.5);
<a name="l00081"></a>00081                 sFloat response = i.key();
<a name="l00082"></a>00082                 <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;drawLine(point+QPointF(-2,0),point+QPointF(+2,0));
<a name="l00083"></a>00083                 <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;drawLine(point+QPointF(0,-2),point+QPointF(0,+2));
<a name="l00084"></a>00084                 <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;<a class="code" href="classQVPainter.html#af213d51b59f8ed1254adb8f2df8f4f98" title="Draws text in a given pixel position of the QVImageCanvas which does not scale with...">drawTextUnscaled</a>(point, QString(<span class="stringliteral">&quot;%1(%2)&quot;</span>).arg(order).arg(-response));
<a name="l00085"></a>00085                 i++;
<a name="l00086"></a>00086                 order++;
<a name="l00087"></a>00087             }
<a name="l00088"></a>00088         };
<a name="l00089"></a>00089 };
<a name="l00090"></a>00090 
<a name="l00091"></a>00091 <span class="keyword">class </span>CannyImageCanvas : <span class="keyword">public</span> <a class="code" href="classQVImageCanvas.html" title="Display widget for QVImage objects and other data types.">QVImageCanvas</a> {
<a name="l00092"></a>00092     <span class="keyword">public</span>:
<a name="l00093"></a>00093         CannyImageCanvas(QString name) : <a class="code" href="classQVImageCanvas.html" title="Display widget for QVImage objects and other data types.">QVImageCanvas</a>(name) {
<a name="l00094"></a>00094             addProperty&lt;int&gt;(<span class="stringliteral">&quot;lr&quot;</span>, inputFlag);
<a name="l00095"></a>00095             addProperty&lt; QList&lt;QLineF&gt; &gt;(<span class="stringliteral">&quot;Regression lines&quot;</span>, inputFlag);
<a name="l00096"></a>00096         } ;
<a name="l00097"></a>00097         <span class="keywordtype">void</span> <a class="code" href="classQVImageCanvas.html#a0040df759739f50e9235547f1055844a" title="Display user defined data types method.">custom_viewer</a>(){
<a name="l00098"></a>00098             <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> poly = getPropertyValue&lt;QVPolyline&gt;(<span class="stringliteral">&quot;poly select&quot;</span>);
<a name="l00099"></a>00099             QList&lt;QLineF&gt; regLines = getPropertyValue&lt; QList&lt;QLineF&gt; &gt;(<span class="stringliteral">&quot;Regression lines&quot;</span>);
<a name="l00100"></a>00100             <span class="keyword">const</span> <span class="keywordtype">int</span> lr = getPropertyValue&lt;int&gt;(<span class="stringliteral">&quot;lr&quot;</span>);
<a name="l00101"></a>00101             <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;setPen(Qt::green);
<a name="l00102"></a>00102             <span class="keywordflow">foreach</span>(QPoint point,poly)
<a name="l00103"></a>00103                 <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;drawRect(point.x()-lr,point.y()-lr,2*lr+1,2*lr+1);
<a name="l00104"></a>00104             <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;setPen(Qt::red);
<a name="l00105"></a>00105             <span class="keywordflow">foreach</span>(QLineF line,regLines)
<a name="l00106"></a>00106                 <a class="code" href="classQVImageCanvas.html#adcc6632a6181cc4d9f9ef3b2e2fb6b22" title="Returns a QVPainter object to perform custom drawings in the canvas.">getQVPainter</a>()-&gt;drawLine(line.translated(0.5,0.5));
<a name="l00107"></a>00107         };
<a name="l00108"></a>00108 };
<a name="l00109"></a>00109 
<a name="l00110"></a>00110 <span class="comment">/************************************** AUXILIARY FUNCTIONS **************************************/</span>
<a name="l00111"></a>00111 
<a name="l00112"></a>00112 <span class="comment">// The following functions illustrate use of main data classes (QVImage, QVMatrix, QVVector, ...) and functions</span>
<a name="l00113"></a>00113 <span class="comment">// (Intel IPP image processing functions, matrix algebra, ...). Native QT classes (like QMap, QList, QPoint, ...) are</span>
<a name="l00114"></a>00114 <span class="comment">// also extensively used:</span>
<a name="l00115"></a>00115 
<a name="l00116"></a>00116 QMap&lt;sFloat,QPointF&gt;  findMaximalPoints(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">double</span> threshold, <span class="keyword">const</span> <span class="keywordtype">int</span> windowRadius)
<a name="l00117"></a>00117 {
<a name="l00118"></a>00118     <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> maxImage;
<a name="l00119"></a>00119     <a class="code" href="group__qvippFF.html#ga30636f7f21a0c31e2be512cd81885276" title="Applies the &amp;quot;max&amp;quot; filter to an image.">FilterMax</a>(image, maxImage,
<a name="l00120"></a>00120               QSize(2*windowRadius+1,2*windowRadius+1), <span class="comment">// Mask size</span>
<a name="l00121"></a>00121               QPoint(0,0), <span class="comment">// Anchor</span>
<a name="l00122"></a>00122               image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(windowRadius, windowRadius) <span class="comment">// Destination</span>
<a name="l00123"></a>00123               );
<a name="l00124"></a>00124 
<a name="l00125"></a>00125     <span class="keyword">const</span> QRect ROI = maxImage.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l00126"></a>00126     <span class="keyword">const</span> <span class="keywordtype">int</span> maxStep = maxImage.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(sFloat),
<a name="l00127"></a>00127               imageStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(sFloat);
<a name="l00128"></a>00128 
<a name="l00129"></a>00129     QMap&lt;sFloat, QPointF&gt; sortedPoints;
<a name="l00130"></a>00130 
<a name="l00131"></a>00131     sFloat *actualPtr = (sFloat *) image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>() + (imageStep + 1) * windowRadius;
<a name="l00132"></a>00132     sFloat *maxPtr = (sFloat *) maxImage.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>() + (maxStep + 1) * windowRadius;
<a name="l00133"></a>00133 
<a name="l00134"></a>00134     <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; ROI.height(); j++, actualPtr += imageStep, maxPtr += maxStep)
<a name="l00135"></a>00135         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; ROI.width(); i++)
<a name="l00136"></a>00136             <span class="keywordflow">if</span> ( (actualPtr[i] &gt;= threshold) and (maxPtr[i] == actualPtr[i]) )
<a name="l00137"></a>00137                 <span class="comment">// We store negative response (QMap sorted in ascending order):</span>
<a name="l00138"></a>00138                 sortedPoints.insertMulti(-actualPtr[i], QPointF(i+ROI.x(), j+ROI.y()));
<a name="l00139"></a>00139 
<a name="l00140"></a>00140     <span class="keywordflow">return</span> sortedPoints;
<a name="l00141"></a>00141 }
<a name="l00142"></a>00142 
<a name="l00143"></a>00143 <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> getCannyImage(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> imageGray, QRect CannyROI, <span class="keyword">const</span> <span class="keywordtype">double</span> thrLow, <span class="keyword">const</span> <span class="keywordtype">double</span> thrHigh)
<a name="l00144"></a>00144 {
<a name="l00145"></a>00145     uInt cols = imageGray.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = imageGray.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l00146"></a>00146     <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> imageFloat(imageGray),dX(cols,rows), dY(cols,rows), dXNeg(cols,rows);
<a name="l00147"></a>00147     <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> imageCanny(cols,rows), buffer;
<a name="l00148"></a>00148 
<a name="l00149"></a>00149     <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> imageDest(imageGray);
<a name="l00150"></a>00150     imageFloat.setROI(CannyROI);
<a name="l00151"></a>00151     imageCanny.setROI(CannyROI);
<a name="l00152"></a>00152     <a class="code" href="group__qvippFF.html#ga80cdf87494c982146fbaf42fa4e1886f" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelHorizMask_32f_C1R.">FilterSobelHorizMask</a>(imageFloat, dY, ippMskSize3x3);
<a name="l00153"></a>00153     <a class="code" href="group__qvippFF.html#gac4c214ba6435857ee9874d2103e99418" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelVertMask_32f_C1R.">FilterSobelVertMask</a>(imageFloat, dX, ippMskSize3x3);
<a name="l00154"></a>00154     <a class="code" href="group__qvippIAALO.html#gadc8a14bd103bb45afa43950ce454f2fd" title="Adds, subtracts, or multiplies pixel values of an image and a constant, and places...">MulC</a>(dX, -1, dXNeg);
<a name="l00155"></a>00155     <a class="code" href="group__qvippCV.html#ga81da042e746aff629cf0e0f45b0f9cb7" title="Allocates size in a buffer image for temporary data for function Canny.This function...">CannyGetSize</a>(imageCanny, buffer);
<a name="l00156"></a>00156     <a class="code" href="group__qvippCV.html#ga56269a74576283f8743352552aadc12a" title="Creates binary image of source&amp;#39;s image edges, using derivatives of the first...">Canny</a>(dXNeg, dY, imageCanny, qMin(thrLow,thrHigh) <span class="comment">/* IPP Canny fails if thrLow &gt; thrHigh */</span>, thrHigh, buffer);
<a name="l00157"></a>00157     Copy(imageCanny, imageDest, QPoint(CannyROI.x(),CannyROI.y()));
<a name="l00158"></a>00158     imageDest.resetROI();
<a name="l00159"></a>00159 
<a name="l00160"></a>00160     <span class="keywordflow">return</span> imageDest;
<a name="l00161"></a>00161 }
<a name="l00162"></a>00162 
<a name="l00163"></a>00163 QList&lt;QLineF&gt; getRegressionLines(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;imageCanny, <span class="keyword">const</span> QRect &amp;CannyROI,
<a name="l00164"></a>00164                                  <span class="keyword">const</span> <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;CannySelPoints, <span class="keywordtype">int</span> lr)
<a name="l00165"></a>00165 {
<a name="l00166"></a>00166     QList&lt;QLineF&gt; regLines;
<a name="l00167"></a>00167     <span class="keywordflow">for</span>(<span class="keywordtype">int</span> k=0;k&lt;CannySelPoints.size();k++) {
<a name="l00168"></a>00168         QPointF mean(0,0);
<a name="l00169"></a>00169         QList&lt;QPointF&gt; listPoints;
<a name="l00170"></a>00170         QPointF point = CannySelPoints[k];
<a name="l00171"></a>00171         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j=point.y()-lr;j&lt;=point.y()+lr;j++)
<a name="l00172"></a>00172             <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=point.x()-lr;i&lt;=point.x()+lr;i++)
<a name="l00173"></a>00173                 <span class="keywordflow">if</span>(CannyROI.contains(i,j))
<a name="l00174"></a>00174                     <span class="keywordflow">if</span>(imageCanny(i,j) == 255) {
<a name="l00175"></a>00175                         listPoints.append(QPointF(i,j));
<a name="l00176"></a>00176                         mean += QPointF(i,j);
<a name="l00177"></a>00177                     }
<a name="l00178"></a>00178         <span class="keyword">const</span> <span class="keywordtype">int</span> n = listPoints.size();
<a name="l00179"></a>00179         <span class="keywordflow">if</span>(n &gt;= 2) { <span class="comment">// Two points minimum to estimate regression line.</span>
<a name="l00180"></a>00180             mean /= n;
<a name="l00181"></a>00181             <a class="code" href="classQVMatrix.html" title="Implementation of numerical matrices.">QVMatrix</a> M(n,2); <span class="comment">// n x 2 matrix;</span>
<a name="l00182"></a>00182             <span class="keywordflow">for</span>(<span class="keywordtype">int</span> k=0;k&lt;n;k++) {
<a name="l00183"></a>00183                 M(k,0) = listPoints[k].x() - mean.x();
<a name="l00184"></a>00184                 M(k,1) = listPoints[k].y() - mean.y();
<a name="l00185"></a>00185             }
<a name="l00186"></a>00186             <a class="code" href="classQVMatrix.html" title="Implementation of numerical matrices.">QVMatrix</a> covMat = M.transpose()*M / n, Q;
<a name="l00187"></a>00187             <a class="code" href="classQVVector.html" title="Implementation of numerical vectors.">QVVector</a> lambda;
<a name="l00188"></a>00188             <a class="code" href="group__qvmatrixalgebra.html#gae95e6a42f2cce467f30a55289a0f9824" title="Obtains the eigen-decomposition of a symmetric matrix.">eigenDecomposition</a>(covMat,lambda,Q);
<a name="l00189"></a>00189             <a class="code" href="classQVVector.html" title="Implementation of numerical vectors.">QVVector</a> mainEigenvector = Q.getCol(0);
<a name="l00190"></a>00190             QPointF pointEV(mainEigenvector(0),mainEigenvector(1));
<a name="l00191"></a>00191             regLines.append(QLineF(mean+lr*pointEV,mean-lr*pointEV));
<a name="l00192"></a>00192         }
<a name="l00193"></a>00193     }
<a name="l00194"></a>00194     <span class="keywordflow">return</span> regLines;
<a name="l00195"></a>00195 }
<a name="l00196"></a>00196 
<a name="l00197"></a>00197 
<a name="l00198"></a>00198 
<a name="l00199"></a>00199 
<a name="l00200"></a>00200 
<a name="l00201"></a>00201 <span class="comment">/************************************** PROCESSING BLOCK(S) **************************************/</span>
<a name="l00202"></a>00202 
<a name="l00203"></a>00203 <span class="comment">// Our customized processing blocks inherit form QVProcessingBlock class. If we are not interested in multithreading,</span>
<a name="l00204"></a>00204 <span class="comment">// we will normally use just one processing block:</span>
<a name="l00205"></a>00205 
<a name="l00206"></a>00206 <span class="keyword">class </span>MyProcessingBlock: <span class="keyword">public</span> <a class="code" href="classQVProcessingBlock.html" title="Base class for Block threads.">QVProcessingBlock</a> {
<a name="l00207"></a>00207     <span class="keyword">private</span>:
<a name="l00208"></a>00208         <a class="code" href="classQVIndexedStringList.html" title="String List with a current string index.">QVIndexedStringList</a> filterList; <span class="comment">// To select from list of strings with automatically generated combobox in GUI.</span>
<a name="l00209"></a>00209 
<a name="l00210"></a>00210     <span class="keyword">public</span>:
<a name="l00211"></a>00211         MyProcessingBlock(QString name = QString()): <a class="code" href="classQVProcessingBlock.html" title="Base class for Block threads.">QVProcessingBlock</a>(name) { <span class="comment">// Constructor</span>
<a name="l00212"></a>00212             <span class="comment">// Add input parameters (bools, ints, doubles, ...). For all of them, corresponding GUI widgets and</span>
<a name="l00213"></a>00213             <span class="comment">// read from command lines are automatically included:</span>
<a name="l00214"></a>00214             addProperty&lt;bool&gt;(<span class="stringliteral">&quot;box&quot;</span>, inputFlag, <span class="keyword">false</span>, <span class="stringliteral">&quot;Apply box filter&quot;</span>);
<a name="l00215"></a>00215             addProperty&lt;int&gt;(<span class="stringliteral">&quot;boxrows&quot;</span>, inputFlag, 3, <span class="stringliteral">&quot;Row box size&quot;</span>, 1, 5);
<a name="l00216"></a>00216             addProperty&lt;int&gt;(<span class="stringliteral">&quot;boxcols&quot;</span>, inputFlag, 3, <span class="stringliteral">&quot;Col box size&quot;</span>, 1, 5);
<a name="l00217"></a>00217             addProperty&lt;double&gt;(<span class="stringliteral">&quot;thhi&quot;</span>, inputFlag, 150, <span class="stringliteral">&quot;High threshold for Canny operator&quot;</span>, 50, 1000);
<a name="l00218"></a>00218             addProperty&lt;double&gt;(<span class="stringliteral">&quot;thlo&quot;</span>, inputFlag, 50, <span class="stringliteral">&quot;Low threshold for Canny operator&quot;</span>, 10, 500);
<a name="l00219"></a>00219             addProperty&lt;double&gt;(<span class="stringliteral">&quot;thMax&quot;</span>, inputFlag, 50, <span class="stringliteral">&quot;Max threshold for Hessian/Harris&quot;</span>, 1.0, 255.0);
<a name="l00220"></a>00220             addProperty&lt;int&gt;(<span class="stringliteral">&quot;lr&quot;</span>, inputFlag|outputFlag, 5, <span class="stringliteral">&quot;Radius for Canny regression lines&quot;</span>, 2, 20);
<a name="l00221"></a>00221 
<a name="l00222"></a>00222             <span class="comment">// Also comboboxes automatically generated in GUI from lists  of strings (QVIndexedStringList properties):</span>
<a name="l00223"></a>00223             filterList.append(<span class="stringliteral">&quot;None&quot;</span>);
<a name="l00224"></a>00224             filterList.append(<span class="stringliteral">&quot;Hessian&quot;</span>);
<a name="l00225"></a>00225             filterList.append(<span class="stringliteral">&quot;Harris&quot;</span>);
<a name="l00226"></a>00226             <span class="comment">// firstFilter.append(&quot;...&quot;);</span>
<a name="l00227"></a>00227             addProperty&lt;QVIndexedStringList&gt;(<span class="stringliteral">&quot;Filter&quot;</span>, inputFlag, filterList, <span class="stringliteral">&quot;Apply corner response filter&quot;</span>);
<a name="l00228"></a>00228 
<a name="l00229"></a>00229             <span class="comment">// ROI rectangle and list of points to be linked as input from corresponding image window:</span>
<a name="l00230"></a>00230             addProperty&lt;QRect&gt;(<span class="stringliteral">&quot;CannyROI&quot;</span>, inputFlag);
<a name="l00231"></a>00231             addProperty&lt;QVPolyline&gt;(<span class="stringliteral">&quot;CannySelPoints&quot;</span>, inputFlag);
<a name="l00232"></a>00232 
<a name="l00233"></a>00233             <span class="comment">// One Input RGB image (3 channels), and two (one channel) output images (one of bytes, other of floats):</span>
<a name="l00234"></a>00234             addProperty&lt; QVImage&lt;uChar,3&gt; &gt;(<span class="stringliteral">&quot;Input RGB image&quot;</span>, inputFlag|outputFlag);
<a name="l00235"></a>00235             addProperty&lt; QVImage&lt;uChar,1&gt; &gt;(<span class="stringliteral">&quot;Output image byte&quot;</span>, outputFlag);
<a name="l00236"></a>00236             addProperty&lt; QVImage&lt;sFloat,1&gt; &gt;(<span class="stringliteral">&quot;Output image float&quot;</span>, outputFlag);
<a name="l00237"></a>00237 
<a name="l00238"></a>00238             <span class="comment">// One output property for list of maximum response points, regression lines and R, G, B histograms:</span>
<a name="l00239"></a>00239             addProperty&lt; QMap&lt;sFloat,QPointF&gt; &gt;(<span class="stringliteral">&quot;Max points&quot;</span>, outputFlag);
<a name="l00240"></a>00240             addProperty&lt; QList&lt;QLineF&gt; &gt;(<span class="stringliteral">&quot;Regression lines&quot;</span>, outputFlag);
<a name="l00241"></a>00241             addProperty&lt; QList&lt;double&gt; &gt;(<span class="stringliteral">&quot;R histogram&quot;</span>, outputFlag);
<a name="l00242"></a>00242             addProperty&lt; QList&lt;double&gt; &gt;(<span class="stringliteral">&quot;G histogram&quot;</span>, outputFlag);
<a name="l00243"></a>00243             addProperty&lt; QList&lt;double&gt; &gt;(<span class="stringliteral">&quot;B histogram&quot;</span>, outputFlag);
<a name="l00244"></a>00244 
<a name="l00245"></a>00245             <span class="comment">// An example trigger button to save a snapshot of current RGB image:</span>
<a name="l00246"></a>00246             <a class="code" href="classQVProcessingBlock.html#a26a8c3ab6758620d7cb328f4dd60b860" title="Adds a trigger to the block.">addTrigger</a>(<span class="stringliteral">&quot;Snapshot&quot;</span>);
<a name="l00247"></a>00247         }
<a name="l00248"></a>00248 
<a name="l00249"></a>00249         <span class="comment">// Generic callback method for trigger buttons:</span>
<a name="l00250"></a>00250         <span class="keywordtype">void</span> <a class="code" href="classQVProcessingBlock.html#adb13844954356bd9ed1bfbe97d731095" title="Process trigger activations in the block.">processTrigger</a>(<span class="keyword">const</span> QString triggerName) {
<a name="l00251"></a>00251             <span class="keywordflow">if</span>(triggerName == <span class="stringliteral">&quot;Snapshot&quot;</span>) {
<a name="l00252"></a>00252                 <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;uchar,3&gt;</a> imageRGB = getPropertyValue&lt; QVImage&lt;uChar,3&gt; &gt;(<span class="stringliteral">&quot;Input RGB image&quot;</span>);
<a name="l00253"></a>00253                 QImage qimage = imageRGB;
<a name="l00254"></a>00254                 qimage.save(<span class="stringliteral">&quot;snapshot.jpg&quot;</span>);
<a name="l00255"></a>00255             } <span class="comment">// else if (triggerName == &quot;...&quot;)</span>
<a name="l00256"></a>00256         }
<a name="l00257"></a>00257 
<a name="l00258"></a>00258         <span class="comment">// Main iteration method for main processing block:</span>
<a name="l00259"></a>00259         <span class="keywordtype">void</span> <a class="code" href="classQVProcessingBlock.html#a0283c799776e0c938538de0b0ae6b463" title="Function to be defined in subclasses with processing code.">iterate</a>() {
<a name="l00260"></a>00260             <span class="comment">// Get input RGB image:</span>
<a name="l00261"></a>00261             <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;uchar,3&gt;</a> imageRGB = getPropertyValue&lt; QVImage&lt;uChar,3&gt; &gt;(<span class="stringliteral">&quot;Input RGB image&quot;</span>);
<a name="l00262"></a>00262 
<a name="l00263"></a>00263             <span class="comment">// Convert RGB image to gray:</span>
<a name="l00264"></a>00264             <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;uchar,1&gt;</a> imageGray = imageRGB;
<a name="l00265"></a>00265 
<a name="l00266"></a>00266             <span class="comment">// Get current values of GUI parameters:</span>
<a name="l00267"></a>00267             <span class="keyword">const</span> <a class="code" href="classQVIndexedStringList.html" title="String List with a current string index.">QVIndexedStringList</a> selectedFilter = getPropertyValue&lt;QVIndexedStringList&gt;(<span class="stringliteral">&quot;Filter&quot;</span>);
<a name="l00268"></a>00268             <span class="keyword">const</span> <span class="keywordtype">bool</span> applyBox = getPropertyValue&lt;bool&gt;(<span class="stringliteral">&quot;box&quot;</span>);
<a name="l00269"></a>00269             <span class="keyword">const</span> <span class="keywordtype">int</span> boxRows = getPropertyValue&lt;int&gt;(<span class="stringliteral">&quot;boxrows&quot;</span>);
<a name="l00270"></a>00270             <span class="keyword">const</span> <span class="keywordtype">int</span> boxCols = getPropertyValue&lt;int&gt;(<span class="stringliteral">&quot;boxcols&quot;</span>);
<a name="l00271"></a>00271             <span class="keyword">const</span> <span class="keywordtype">double</span> thrLow = getPropertyValue&lt;double&gt;(<span class="stringliteral">&quot;thhi&quot;</span>);
<a name="l00272"></a>00272             <span class="keyword">const</span> <span class="keywordtype">double</span> thrHigh = getPropertyValue&lt;double&gt;(<span class="stringliteral">&quot;thlo&quot;</span>);
<a name="l00273"></a>00273             <span class="keyword">const</span> <span class="keywordtype">double</span> thMax = getPropertyValue&lt;double&gt;(<span class="stringliteral">&quot;thMax&quot;</span>);
<a name="l00274"></a>00274             <span class="keyword">const</span> <span class="keywordtype">int</span> lr = getPropertyValue&lt;int&gt;(<span class="stringliteral">&quot;lr&quot;</span>);
<a name="l00275"></a>00275 
<a name="l00276"></a>00276             <span class="comment">// Read GUI input linked from image windows:</span>
<a name="l00277"></a>00277             QRect CannyROI = getPropertyValue&lt;QRect&gt;(<span class="stringliteral">&quot;CannyROI&quot;</span>);
<a name="l00278"></a>00278             <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> CannySelPoints = getPropertyValue&lt;QVPolyline&gt;(<span class="stringliteral">&quot;CannySelPoints&quot;</span>);
<a name="l00279"></a>00279 
<a name="l00280"></a>00280             <span class="comment">// Time statistics (put one after each stage of computation):</span>
<a name="l00281"></a>00281             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Read input parameters&quot;</span>);
<a name="l00282"></a>00282 
<a name="l00283"></a>00283             <span class="comment">// First, we compute the Canny operator on the byte image (ouput will be binary, 0 or 255 values):</span>
<a name="l00284"></a>00284             uInt cols = imageGray.getCols(), rows = imageGray.getRows();
<a name="l00285"></a>00285 
<a name="l00286"></a>00286             <span class="comment">// Define ROI for Canny:</span>
<a name="l00287"></a>00287             <span class="keywordtype">bool</span> computeCanny = <span class="keyword">true</span>;
<a name="l00288"></a>00288             <span class="keywordflow">if</span> (CannyROI == QRect()) {
<a name="l00289"></a>00289                 <span class="comment">// User did not select rectangle: work in whole image:</span>
<a name="l00290"></a>00290                 CannyROI = imageGray.getROI();
<a name="l00291"></a>00291             } <span class="keywordflow">else</span> <span class="keywordflow">if</span>(CannyROI.height()&gt;=5 and CannyROI.width()&gt;=5) {
<a name="l00292"></a>00292                 <span class="comment">// If rectangle by user is big enough, define ROI accordingly:</span>
<a name="l00293"></a>00293                 <span class="keywordflow">if</span>(CannyROI.bottom() == <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(rows)-1)
<a name="l00294"></a>00294                     CannyROI.setBottom(CannyROI.bottom()-1); <span class="comment">// Solves IPP boundary problem in Canny function.</span>
<a name="l00295"></a>00295             } <span class="keywordflow">else</span> {
<a name="l00296"></a>00296                 <span class="comment">// Problematic ROI (too small ROI) for IPP Canny function: do not compute Canny image:</span>
<a name="l00297"></a>00297                 computeCanny = <span class="keyword">false</span>;
<a name="l00298"></a>00298             }
<a name="l00299"></a>00299 
<a name="l00300"></a>00300             <span class="comment">// Obtain Canny image (only in selected region of interest (ROI):</span>
<a name="l00301"></a>00301             <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> imageCanny;
<a name="l00302"></a>00302             <span class="keywordflow">if</span>(computeCanny)
<a name="l00303"></a>00303                 imageCanny = getCannyImage(imageGray,CannyROI,thrLow,thrHigh);
<a name="l00304"></a>00304             <span class="keywordflow">else</span>
<a name="l00305"></a>00305                 imageCanny = imageGray;
<a name="l00306"></a>00306 
<a name="l00307"></a>00307             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Canny operator&quot;</span>);
<a name="l00308"></a>00308 
<a name="l00309"></a>00309             <span class="comment">// Get regression lines on every input square marked by user:</span>
<a name="l00310"></a>00310             QList&lt;QLineF&gt; regLines = getRegressionLines(imageCanny,CannyROI,CannySelPoints,lr);
<a name="l00311"></a>00311 
<a name="l00312"></a>00312             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Regression lines&quot;</span>);
<a name="l00313"></a>00313 
<a name="l00314"></a>00314             <span class="comment">// If corresponding checkbox selected, previously apply box filter with requested box size values:</span>
<a name="l00315"></a>00315             <span class="keywordflow">if</span>(applyBox) {
<a name="l00316"></a>00316                 <span class="comment">// We need an auxiliary image, because IPP FilterBox is not an inplace operation:</span>
<a name="l00317"></a>00317                 <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> imageGray2(cols,rows);
<a name="l00318"></a>00318                 <a class="code" href="group__qvippFF.html#ga2d118e9683ff100e1ae96b54158040ca" title="QVision wrapper function for IPP&amp;#39;s ippiFilterBox_8u_C1R.">FilterBox</a>(imageGray, imageGray2, QSize(boxCols,boxRows),
<a name="l00319"></a>00319                           <span class="comment">/*anchor*/</span> QPoint(0,0),<span class="comment">/* destROIOffset */</span> QPoint(boxCols/2,boxRows/2));
<a name="l00320"></a>00320                 imageGray = imageGray2;
<a name="l00321"></a>00321                 <span class="comment">// Recover original ROI (which was reduced by FilterBox):</span>
<a name="l00322"></a>00322                 imageGray.resetROI();
<a name="l00323"></a>00323             }
<a name="l00324"></a>00324             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Box filter&quot;</span>);
<a name="l00325"></a>00325 
<a name="l00326"></a>00326             <span class="comment">// Apply selected response filter:</span>
<a name="l00327"></a>00327             <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> imageFloat(cols,rows);
<a name="l00328"></a>00328             <span class="keywordtype">int</span> choice = selectedFilter.<a class="code" href="classQVIndexedStringList.html#a9855746cb07868930d17476bab48f251" title="Return the index.">getIndex</a>();
<a name="l00329"></a>00329             <span class="keywordflow">switch</span> (choice) {
<a name="l00330"></a>00330                 <span class="keywordflow">case</span> 0: { <span class="comment">// None</span>
<a name="l00331"></a>00331                     imageFloat = imageGray;
<a name="l00332"></a>00332                     <span class="keywordflow">break</span>;
<a name="l00333"></a>00333                 }
<a name="l00334"></a>00334                 <span class="keywordflow">case</span> 1: { <span class="comment">// Hessian</span>
<a name="l00335"></a>00335                     <a class="code" href="group__qvipp.html#ga5e1dd92e6da496d1e621861eb2b67cf9" title="Obtains the Hessian corner response image.">FilterHessianCornerResponseImage</a>(imageGray, imageFloat, <span class="comment">/* destROIOffset */</span> QPoint(2,2));
<a name="l00336"></a>00336                     <span class="keywordflow">break</span>;
<a name="l00337"></a>00337                 }
<a name="l00338"></a>00338                 <span class="keywordflow">case</span> 2: { <span class="comment">// Harris</span>
<a name="l00339"></a>00339                     <a class="code" href="group__qvipp.html#ga500350a4e3dc3d05b99bd034ab65a67b" title="Obtains the Harris corner response image.">FilterHarrisCornerResponseImage</a>(imageGray, imageFloat);
<a name="l00340"></a>00340                     <span class="comment">// Underlying direct IPP call, no need for destROIoffset.</span>
<a name="l00341"></a>00341                     <span class="keywordflow">break</span>;
<a name="l00342"></a>00342                 }
<a name="l00343"></a>00343             }
<a name="l00344"></a>00344             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Corner response filter&quot;</span>);
<a name="l00345"></a>00345 
<a name="l00346"></a>00346             <span class="comment">// Recover original ROI (which was reduced by previous filters Hessian/Harris):</span>
<a name="l00347"></a>00347             imageFloat.resetROI();
<a name="l00348"></a>00348 
<a name="l00349"></a>00349             <span class="comment">// Normalize float image to get values in [0..255]:</span>
<a name="l00350"></a>00350             FilterNormalize(imageFloat, imageFloat);
<a name="l00351"></a>00351 
<a name="l00352"></a>00352             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Normalization&quot;</span>);
<a name="l00353"></a>00353 
<a name="l00354"></a>00354             QMap&lt;sFloat,QPointF&gt; maxPoints;
<a name="l00355"></a>00355             <span class="keywordflow">if</span>(choice != 0) {
<a name="l00356"></a>00356                 <span class="keyword">const</span> <span class="keywordtype">int</span> radius = 3;
<a name="l00357"></a>00357                 maxPoints = findMaximalPoints(imageFloat, thMax, radius);
<a name="l00358"></a>00358             }
<a name="l00359"></a>00359             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Get maximum response points&quot;</span>);
<a name="l00360"></a>00360 
<a name="l00361"></a>00361             <span class="comment">// Histograms of R, G, B channels:</span>
<a name="l00362"></a>00362             <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> selected;
<a name="l00363"></a>00363             Copy(imageRGB,0,selected);
<a name="l00364"></a>00364             <span class="keyword">const</span> QVector&lt;int&gt; RHistogramInt = <a class="code" href="group__qvipp.html#gae25c99f8b8e1975910a913eaa8d41d96" title="Calculates frequency histogram for a given set of values, for a QVImageThis function...">HistogramRange</a>(selected);
<a name="l00365"></a>00365             Copy(imageRGB,1,selected);
<a name="l00366"></a>00366             <span class="keyword">const</span> QVector&lt;int&gt; GHistogramInt = <a class="code" href="group__qvipp.html#gae25c99f8b8e1975910a913eaa8d41d96" title="Calculates frequency histogram for a given set of values, for a QVImageThis function...">HistogramRange</a>(selected);
<a name="l00367"></a>00367             Copy(imageRGB,2,selected);
<a name="l00368"></a>00368             <span class="keyword">const</span> QVector&lt;int&gt; BHistogramInt = <a class="code" href="group__qvipp.html#gae25c99f8b8e1975910a913eaa8d41d96" title="Calculates frequency histogram for a given set of values, for a QVImageThis function...">HistogramRange</a>(selected);
<a name="l00369"></a>00369 
<a name="l00370"></a>00370             QList&lt;double&gt; RHistogram,GHistogram,BHistogram;
<a name="l00371"></a>00371             <span class="keywordflow">foreach</span>(<span class="keywordtype">int</span> val,RHistogramInt)
<a name="l00372"></a>00372                 RHistogram.append(val);
<a name="l00373"></a>00373             <span class="keywordflow">foreach</span>(<span class="keywordtype">int</span> val,GHistogramInt)
<a name="l00374"></a>00374                 GHistogram.append(val);
<a name="l00375"></a>00375             <span class="keywordflow">foreach</span>(<span class="keywordtype">int</span> val,BHistogramInt)
<a name="l00376"></a>00376                 BHistogram.append(val);
<a name="l00377"></a>00377 
<a name="l00378"></a>00378             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Obtain RGB histograms&quot;</span>);
<a name="l00379"></a>00379 
<a name="l00380"></a>00380             <span class="comment">// Finally, we set the output properties to their corresponding values:</span>
<a name="l00381"></a>00381             setPropertyValue&lt; QVImage&lt;uchar,1&gt; &gt;(<span class="stringliteral">&quot;Output image byte&quot;</span>, imageCanny);
<a name="l00382"></a>00382             setPropertyValue&lt; QVImage&lt;sFloat,1&gt; &gt;(<span class="stringliteral">&quot;Output image float&quot;</span>, imageFloat);
<a name="l00383"></a>00383             setPropertyValue&lt; QMap&lt;sFloat,QPointF&gt; &gt;(<span class="stringliteral">&quot;Max points&quot;</span>, maxPoints);
<a name="l00384"></a>00384             setPropertyValue&lt; QList&lt;QLineF&gt; &gt;(<span class="stringliteral">&quot;Regression lines&quot;</span>, regLines);
<a name="l00385"></a>00385             setPropertyValue&lt; QList&lt;double&gt; &gt;(<span class="stringliteral">&quot;R histogram&quot;</span>, RHistogram);
<a name="l00386"></a>00386             setPropertyValue&lt; QList&lt;double&gt; &gt;(<span class="stringliteral">&quot;G histogram&quot;</span>, GHistogram);
<a name="l00387"></a>00387             setPropertyValue&lt; QList&lt;double&gt; &gt;(<span class="stringliteral">&quot;B histogram&quot;</span>, BHistogram);
<a name="l00388"></a>00388 
<a name="l00389"></a>00389             <a class="code" href="classQVProcessingBlock.html#a61f390e8790a77175a6d6e1049a9d127" title="Stablish a performance breakpoint in the execution of the block.">timeFlag</a>(<span class="stringliteral">&quot;Write output parameters&quot;</span>);
<a name="l00390"></a>00390             }
<a name="l00391"></a>00391         };
<a name="l00392"></a>00392 
<a name="l00393"></a>00393 <span class="comment">// Main function always has the same structure:</span>
<a name="l00394"></a>00394 <span class="comment">//   1. Create a QVApplication object.</span>
<a name="l00395"></a>00395 <span class="comment">//   2. Create image source block(s)</span>
<a name="l00396"></a>00396 <span class="comment">//   3. Create main processing block(s) (in our case, just one MyProcessingBlock).</span>
<a name="l00397"></a>00397 <span class="comment">//   4. Create main GUI (QVDefaultGUI) and extra GUI elements (QVImageCanvas and subclasses,QVFunctionPlot, ...),</span>
<a name="l00398"></a>00398 <span class="comment">//   5. Adequately link properties among objects of type 2-4.</span>
<a name="l00399"></a>00399 <span class="comment">//   6. Call exec method on QVApplication.</span>
<a name="l00400"></a>00400 <span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) {
<a name="l00401"></a>00401     <span class="comment">// Application:</span>
<a name="l00402"></a>00402     <a class="code" href="classQVApplication.html" title="Main class for QVision applications.">QVApplication</a> app(argc, argv, <span class="stringliteral">&quot;Example program for QVision library.&quot;</span>);
<a name="l00403"></a>00403 
<a name="l00404"></a>00404     <span class="comment">// Image sources:</span>
<a name="l00405"></a>00405     <a class="code" href="classQVVideoReaderBlock.html" title="This is a generic video input processing block for the QVision architecture.">QVVideoReaderBlock</a> camera(<span class="stringliteral">&quot;Video&quot;</span>);
<a name="l00406"></a>00406 
<a name="l00407"></a>00407     <span class="comment">// Processing blocks:</span>
<a name="l00408"></a>00408     MyProcessingBlock filterBlock(<span class="stringliteral">&quot;Image filter block&quot;</span>);
<a name="l00409"></a>00409 
<a name="l00410"></a>00410     <span class="comment">// GUI elements:</span>
<a name="l00411"></a>00411     <a class="code" href="classQVDefaultGUI.html" title="Main user interface widget for QVision applications.">QVDefaultGUI</a> interface;
<a name="l00412"></a>00412     <a class="code" href="classQVImageCanvas.html" title="Display widget for QVImage objects and other data types.">QVImageCanvas</a> inputImage(<span class="stringliteral">&quot;Input RGB image&quot;</span>);
<a name="l00413"></a>00413     CannyImageCanvas outputImageByte(<span class="stringliteral">&quot;Output image byte&quot;</span>);
<a name="l00414"></a>00414     ResponseImageCanvas outputImageFloat(<span class="stringliteral">&quot;Output image float&quot;</span>);
<a name="l00415"></a>00415     <a class="code" href="classQVFunctionPlot.html" title="Widget for plotting QList&amp;lt;double&amp;gt; property values from a block, as an histogram...">QVFunctionPlot</a> RGBHistogramPlot(<span class="stringliteral">&quot;RGB histogram&quot;</span>);
<a name="l00416"></a>00416 
<a name="l00417"></a>00417     <span class="comment">// Link properties:</span>
<a name="l00418"></a>00418     camera.linkProperty(&amp;filterBlock,<span class="stringliteral">&quot;Input RGB image&quot;</span>);
<a name="l00419"></a>00419 
<a name="l00420"></a>00420     filterBlock.linkProperty(<span class="stringliteral">&quot;Input RGB image&quot;</span>, inputImage);
<a name="l00421"></a>00421     filterBlock.linkProperty(<span class="stringliteral">&quot;Output image byte&quot;</span>, outputImageByte);
<a name="l00422"></a>00422     filterBlock.linkProperty(<span class="stringliteral">&quot;Regression lines&quot;</span>, outputImageByte, <span class="stringliteral">&quot;Regression lines&quot;</span>);
<a name="l00423"></a>00423     filterBlock.linkProperty(<span class="stringliteral">&quot;Output image float&quot;</span>, outputImageFloat);
<a name="l00424"></a>00424     filterBlock.linkProperty(<span class="stringliteral">&quot;Max points&quot;</span>, outputImageFloat,<span class="stringliteral">&quot;Max points&quot;</span>);
<a name="l00425"></a>00425     filterBlock.linkProperty(<span class="stringliteral">&quot;lr&quot;</span>,outputImageByte,<span class="stringliteral">&quot;lr&quot;</span>);
<a name="l00426"></a>00426     filterBlock.linkProperty(<span class="stringliteral">&quot;R histogram&quot;</span>,RGBHistogramPlot);
<a name="l00427"></a>00427     filterBlock.linkProperty(<span class="stringliteral">&quot;G histogram&quot;</span>,RGBHistogramPlot);
<a name="l00428"></a>00428     filterBlock.linkProperty(<span class="stringliteral">&quot;B histogram&quot;</span>,RGBHistogramPlot);
<a name="l00429"></a>00429     outputImageByte.linkSelectedRectangle(filterBlock,<span class="stringliteral">&quot;CannyROI&quot;</span>);
<a name="l00430"></a>00430     outputImageByte.linkSelectedPolyline(filterBlock,<span class="stringliteral">&quot;CannySelPoints&quot;</span>);
<a name="l00431"></a>00431 
<a name="l00432"></a>00432     <span class="comment">// Execute application:</span>
<a name="l00433"></a>00433     <span class="keywordflow">return</span> app.exec();
<a name="l00434"></a>00434 }
<a name="l00435"></a>00435 
<a name="l00436"></a>00436 <span class="preprocessor">#endif</span>
<a name="l00437"></a>00437 <span class="preprocessor"></span>
<a name="l00438"></a>00438 
</pre></div></div>
</td></tr></table>

<br /><hr><br />
<center><a href="http://perception.inf.um.es/QVision">QVision framework</a>.
<a href="http://perception.inf.um.es">PARP research group</a>.
Copyright &copy; 2007, 2008, 2009, 2010, 2011.</center>
<br />
</body>
</html>
